/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpr.inf.escel.brain.operators;

import br.ufpr.inf.escel.brain.model.DadoTeste;
import br.ufpr.inf.escel.brain.model.po.DadoTestePO;
import br.ufpr.inf.escel.brain.model.po.Metodo;
import br.ufpr.inf.escel.brain.model.po.Metodos;
import br.ufpr.inf.escel.brain.model.po.Parametros;
import br.ufpr.inf.escel.brain.operators.util.MutacaoUtils;
import br.ufpr.inf.escel.brain.variator.Variator;

/**
 *
 * @author gustavo
 */
public final class OperadoresPO extends Operadores {

    /**
     * {@inheritDoc}
     */
    public DadoTeste cruzar(DadoTeste dt1, DadoTeste dt2) {

        Metodos metodos = new Metodos();
        Parametros parametros = new Parametros();

        int primeirosMetodos = ((DadoTestePO) dt1).getMetodos().quantidade() / 2;
        int ultimosMetodos = ((DadoTestePO) dt2).getMetodos().quantidade() / 2;

        Metodo metodo = null;

        for (int i = 0; i < primeirosMetodos; i++) {
            metodo = ((DadoTestePO) dt1).getMetodos().getMetodo(i);
            metodos.adicionarMetodo(metodo);
            Parametros params = ((DadoTestePO) dt1).getParamsByMethod(metodo);
            parametros.adicionarParametros(params);
        }

        for (int i = 0; i < ultimosMetodos; i++) {
            metodo = ((DadoTestePO) dt2).getMetodos().getMetodo(i);
            metodos.adicionarMetodo(metodo);
            Parametros params = ((DadoTestePO) dt2).getParamsByMethod(metodo);
            parametros.adicionarParametros(params);
        }

        return new DadoTestePO(metodos, parametros);
    }

    /**
     * tipoMutacao <= 0.33
     *      - mutação no valor de entrada
     * tipoMutação > 0.33 e <= 0.66
     *      - inserção de um novo metodo e seu valor (caso exista)
     * tipoMutação > 0.66
     *      - remoção de um método e seu valor (caso exista)
     *
     * {@inheritDoc}
     */
    @Override
    public DadoTeste mutar(DadoTeste dt) {
        double tipoMutacao = Variator.randomGenerator.nextDouble();

        MutacaoUtils mutar = MutacaoUtils.getInstance();

        if (tipoMutacao <= 0.33) {
            dt = mutar.valorEntrada((DadoTestePO) dt);
        } else if (tipoMutacao > 0.33 && tipoMutacao <= 0.66) {
            dt = mutar.inserirInvocacaoMetodo((DadoTestePO) dt);
        } else if (tipoMutacao > 0.66) {
            dt = mutar.removerInvocacaoMetodo((DadoTestePO) dt);
        }

        return dt;
    }
}
